package com.augmentum.login.controller;

import java.util.ArrayList;
import java.util.List;

import javax.annotation.Resource;
import javax.servlet.http.HttpSession;

import org.apache.log4j.Logger;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.view.RedirectView;

import com.augmentum.login.AppContent;
import com.augmentum.login.Constants;
import com.augmentum.login.exception.ParamException;
import com.augmentum.login.exception.ServiceException;
import com.augmentum.login.model.Exam;
import com.augmentum.login.model.Page;
import com.augmentum.login.service.ExamService;
import com.augmentum.login.service.QuestionService;
import com.augmentum.login.util.PathUtil;
import com.augmentum.login.util.Prop;
import com.augmentum.login.util.Regular;
import com.augmentum.login.util.StringUtil;

@Controller("examController")
@RequestMapping("/page/exam")
public class ExamController extends BaseController {
    private final Logger logger = Logger.getLogger(ExamController.class);
    @Resource
    private ExamService examService;
    @Resource
    private QuestionService questionService;

    @RequestMapping(value = "/create", method = {RequestMethod.POST,RequestMethod.GET})
    public ModelAndView create(
            @RequestParam(value = "name", defaultValue="") String examName,
            @RequestParam(value = "description", defaultValue="") String description,
            @RequestParam(value = "questionCount") Integer questionCount,
            @RequestParam(value = "questionScore") Integer questionScore,
            @RequestParam(value = "totalScore") Integer totalScore,
            @RequestParam(value = "duration") Integer duration,
            @RequestParam(value = "beginDate", defaultValue="") String beginDate,
            @RequestParam(value = "beginHour", defaultValue="") String beginHour,
            @RequestParam(value = "beginMin", defaultValue="") String beginMin,
            @RequestParam(value = "criteria") Integer criteria,
            @RequestParam(value = "state") Integer state) {

        ModelAndView modelView = new ModelAndView();
        HttpSession session = (HttpSession) AppContent.getAppContent().getSession();
        try {
            Exam exam = new Exam();
            String beginTime = beginDate + " " + beginHour + ":" + beginMin;
            criteria = criteria == null ? 0 : criteria;
            questionCount = questionCount == null ? 0 : questionCount;
            questionScore = questionScore == null ? 0 : questionScore;
            totalScore = totalScore == null ? 0 : totalScore;
            duration = duration == null ? 0 : duration;
            state = state == null ? 0 : state;
            exam.setBeginTime(beginTime);
            exam.setCriteria(criteria);
            exam.setDescription(description);
            exam.setName(examName);
            exam.setQuestionCount(questionCount);
            exam.setQuestionScore(questionScore);
            exam.setTotalScore(totalScore);
            exam.setDuration(duration);
            exam.setState(state);
            examService.addExam(exam);

            modelView.setView(new RedirectView(PathUtil.getFullPath(Constants.SEARCH_EXAM_SERVLET)));
            return modelView;
        } catch (ParamException paremException) {
            logger.warn(paremException.getMessage());
            modelView.setView(new RedirectView(PathUtil.getFullPath(Constants.CREATE_EXAM_PAGE)));
            session.setAttribute(Constants.EXAM_MSG, paremException.getExceptionFields());
            return modelView;
        } catch (ServiceException serviceException) {
            logger.warn(serviceException.getMessage());
            modelView.setView(new RedirectView(PathUtil.getFullPath(Constants.CREATE_EXAM_PAGE)));
            session.setAttribute(Constants.EXAM_SERVICE_MSG, serviceException.getMessage());
            return modelView;
        }
    }

    @ResponseBody
    @RequestMapping(value = "/checkQuestionCount/{questionCount}", method = RequestMethod.GET)
    public boolean checkQuestionCount(@PathVariable Integer questionCount) {
        if (questionCount == null) {
            questionCount = 0;
        }
        return questionService.getQuestionCount("") - questionCount > 0;
    }

    @RequestMapping("/search")
    public ModelAndView search(@RequestParam(value = Constants.DESCRIPTION, defaultValue = "") String description,
            @RequestParam(value = Constants.EXAM_NAME, defaultValue = "") String examName,
            @RequestParam(value = Constants.ORDER, defaultValue = "") String order,
            @RequestParam(value = Constants.CURRENTPAGE, defaultValue = "") String currentPage,
            @RequestParam(value = Constants.PAGE_SIEZ, defaultValue = "") String pageSize) {
        ModelAndView modelView = new ModelAndView();
        Page page = new Page();
        if (StringUtil.isEmpty(description)) {
            description = Constants.EMPTY_STRING;
        } else {
            description = StringUtil.replaceSpecialChars(description);
        }

        if (StringUtil.isEmpty(examName)) {
            examName = Constants.EMPTY_STRING;
        } else {
            examName = StringUtil.replaceSpecialChars(examName);
        }

        if (StringUtil.isEmpty(order)) {
            order = Constants.EMPTY_STRING;
        } else if (!order.matches(Regular.ORDER.getValue())) {
            order = Constants.EMPTY_STRING;
        }

        int totalCount = examService.getExamCount(examName, description);
        if (totalCount <= 0) {
            page.setTotalCount(1);
            page.setCurrentPage(1);
            page.setPageSize(Integer.parseInt(Prop.get(Constants.PAGE_SIEZ)));
            modelView.addObject(Constants.PAGE, page);
            modelView.addObject(Constants.EXAM_LIST, new ArrayList<Exam>());
            modelView.setViewName(Constants.EXAM_LIST_JSP);
            return modelView;
        }
        if (StringUtil.isEmpty(currentPage)) {
            currentPage = "1";
        }

        if (!currentPage.matches(Regular.DIGIT.getValue())) {
            currentPage = "1";
        }

        if (StringUtil.isEmpty(pageSize) || !pageSize.matches(Regular.NUMBER.getValue())) {
            pageSize = Prop.get(Constants.PAGE_SIEZ); // set default value
        }

        page.setPageSize(Integer.parseInt(pageSize));
        page.setTotalCount(totalCount);
        int pageNum = Integer.parseInt(currentPage);
        if (pageNum < 1) {
            pageNum = 1;
        } else if (pageNum > page.getPageCount()) {
            pageNum = page.getPageCount();
        }
        page.setCurrentPage(pageNum);
        List<Exam> list = examService.searchExamsByPage(examName, description, order, page);
        modelView.addObject(Constants.DESCRIPTION, description);
        modelView.addObject(Constants.EXAM_NAME, examName);
        modelView.addObject(Constants.ORDER, order);
        modelView.addObject(Constants.PAGE, page);

        modelView.addObject(Constants.EXAM_LIST, list);
        modelView.setViewName(Constants.EXAM_LIST_JSP);
        return modelView;
    }

    @RequestMapping("/edit")
    public ModelAndView edit(
            @RequestParam(value = "id") int id,
            @RequestParam(value = "description") String description,
            @RequestParam(value = "questionCount") Integer questionCount,
            @RequestParam(value = "questionScore") Integer questionScore,
            @RequestParam(value = "totalScore") Integer totalScore,
            @RequestParam(value = "duration") Integer duration,
            @RequestParam(value = "beginDate") String beginDate,
            @RequestParam(value = "beginHour") String beginHour,
            @RequestParam(value = "beginMin") String beginMin,
            @RequestParam(value = "criteria") Integer criteria,
            @RequestParam(value = "state") Integer state,
            @RequestParam(value = "changeCount") Integer changeCount) {
        ModelAndView modelView = new ModelAndView();

        Exam exam = new Exam();
        String beginTime = beginDate + " " + beginHour + ":" + beginMin;
        exam.setBeginTime(beginTime);
        criteria = criteria == null ? 0 : criteria;
        questionCount = questionCount == null ? 0 : questionCount;
        questionScore = questionScore == null ? 0 : questionScore;
        totalScore = totalScore == null ? 0 : totalScore;
        duration = duration == null ? 0 : duration;
        state = state == null ? 0 : state;
        changeCount = changeCount == null ? 0 :changeCount;
        exam.setId(id);
        exam.setCriteria(criteria);
        exam.setDescription(description);
        exam.setQuestionCount(questionCount);
        exam.setQuestionScore(questionScore);
        exam.setTotalScore(totalScore);
        exam.setDuration(duration);
        exam.setState(state);
        exam.setChangeCount(changeCount);

        try {
            examService.modifyExam(exam);
            modelView.setView(new RedirectView(PathUtil.getFullPath(Constants.SEARCH_EXAM_SERVLET)));
            return modelView;
        } catch (ParamException paramException) {
            modelView.setViewName(Constants.EXAM_EDIT_JSP);
            modelView.addObject(Constants.EXAM, exam);
            return modelView;
        }
    }

    @RequestMapping("/draftSearch")
    public ModelAndView search(
            @RequestParam(value = Constants.EXAM_NAME, defaultValue = "") String examName,
            @RequestParam(value = Constants.CURRENTPAGE, defaultValue = "") String currentPage,
            @RequestParam(value = Constants.PAGE_SIEZ, defaultValue = "") String pageSize) {
        ModelAndView modelView = new ModelAndView();
        Page page = new Page();

        if (StringUtil.isEmpty(examName)) {
            examName = "";
        } else {
            examName = StringUtil.replaceSpecialChars(examName);
        }

        int totalCount = examService.getDraftCount(examName);
        if (totalCount <= 0) {
            page.setTotalCount(1);
            page.setCurrentPage(1);
            page.setPageSize(Integer.parseInt(Prop.get(Constants.PAGE_SIEZ)));
            modelView.addObject(Constants.PAGE, page);
            modelView.addObject(Constants.EXAM_LIST, new ArrayList<Exam>());
            modelView.setViewName(Constants.DRAFT_LIST_JSP);
            return modelView;
        }
        if (StringUtil.isEmpty(currentPage)) {
            currentPage = "1";
        }

        if (!currentPage.matches(Regular.DIGIT.getValue())) {
            currentPage = "1";
        }

        if (StringUtil.isEmpty(pageSize) || !pageSize.matches(Regular.NUMBER.getValue())) {
            pageSize = Prop.get(Constants.PAGE_SIEZ); // set default value
        }

        page.setPageSize(Integer.parseInt(pageSize));
        page.setTotalCount(totalCount);
        int pageNum = Integer.parseInt(currentPage);
        if (pageNum < 1) {
            pageNum = 1;
        } else if (pageNum > page.getPageCount()) {
            pageNum = page.getPageCount();
        }
        page.setCurrentPage(pageNum);
        List<Exam> list = examService.searchDraftByPage(examName, page);
        modelView.addObject(Constants.EXAM_NAME, examName);
        modelView.addObject(Constants.PAGE, page);
        modelView.addObject(Constants.EXAM_LIST, list);
        modelView.setViewName(Constants.DRAFT_LIST_JSP);
        return modelView;
    }

    @RequestMapping("/createPage")
    public ModelAndView createPage() {
        ModelAndView modelView = new ModelAndView();
        modelView.setViewName(Constants.CREATE_EXAM_JSP);
        return modelView;
    }

    @RequestMapping("/editPage")
    public ModelAndView editPage(@RequestParam(value = "id") int id) {
        ModelAndView modelView = new ModelAndView();

        Exam exam = examService.getExamById(id);
        if (exam == null) {
            modelView.setView(new RedirectView(PathUtil.getFullPath(Constants.SEARCH_EXAM_SERVLET)));
            return modelView;
        }
        String dateTime = exam.getBeginTime();
        String[] dateAndTime = dateTime.split(" ");
        String date = dateAndTime[0];
        String[] time = dateAndTime[1].split(":");
        String hour = time[0];
        String min = time[1];
        modelView.addObject(Constants.EXAM, exam);
        modelView.addObject("date", date);
        modelView.addObject("hour", hour);
        modelView.addObject("min", min);
        modelView.setViewName(Constants.EXAM_EDIT_JSP);
        return modelView;
    }
    
    @RequestMapping("/delete")
    public ModelAndView delete(
            @RequestParam(value = "examStr") String examStr,
            @RequestParam(value = "state") int state) {
        ModelAndView modelView = new ModelAndView();
        examService.removeBathExams(examStr, ",", state);
        modelView.setView(new RedirectView(PathUtil.getFullPath(Constants.SEARCH_EXAM_SERVLET)));
        return modelView;
    }
}
